package core

import (
	"fmt"
	"sort"
)

type Mj struct {
	Wan  []int //万
	Tong []int //筒
	Tiao []int //条
	All  []int //牌池
}

var mj *Mj

func init() {
	wan := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}           //对应1~9万
	tong := []int{11, 12, 13, 14, 15, 16, 17, 18, 19} //对应1~9筒
	tiao := []int{21, 22, 23, 24, 25, 26, 27, 28, 29} //对应1~9条
	all := make([]int, 0)                             //血流成河麻将只有三副牌【万筒条】，合计108张
	for i := 0; i < 4; i++ {
		all = append(all, wan...)
		all = append(all, tong...)
		all = append(all, tiao...)
	}
	sort.Ints(all)
	mj = &Mj{wan, tong, tiao, all}
}

func GetMj() *Mj {
	return mj
}

func (m *Mj) arrayCountValues(data []int) map[int]int {
	countValues := map[int]int{}
	for _, card := range data {
		countValues[card] += 1
	}
	return countValues
}

func (m *Mj) SumArray(data []int) int {
	sum := 0
	for _, num := range data {
		sum += num
	}
	return sum
}

func (m *Mj) SumMap(data map[int]int) int {
	sum := 0
	for _, num := range data {
		sum += num
	}
	return sum
}

func (m *Mj) DeepCopy(data map[int]int) map[int]int {
	newMap := make(map[int]int, len(data))
	for k, v := range data {
		newMap[k] = v
	}
	return newMap
}

func (m *Mj) getMapKeys(data map[int]int) []int {
	keys := make([]int, 0, len(data))
	for k, _ := range data {
		keys = append(keys, k)
	}
	//给key排序一下
	sort.Ints(keys)
	return keys
}

func (m *Mj) CheckHu(cards []int) ([][]int, bool) {
	jiang := make([]int, 0)
	shun := make([][]int, 0)
	ke := make([][]int, 0)
	rs := m.arrayCountValues(cards)
	huRes, ok := m.CheckQidui(rs)
	if ok {
		return huRes, ok
	}
	fmt.Printf("rs : %v \n", rs)
	//找出适合做将的牌
	for card, num := range rs {
		if num >= 2 {
			jiang = append(jiang, card)
		}
		sort.Ints(jiang)
	}
	fmt.Printf("jiang : %v \n", jiang)
	keys := mj.getMapKeys(rs)
	fmt.Printf("keys : %v \n", keys)
	//依次根据找出的将牌数据进行筛选，顺子和刻子的组合
	for _, card := range jiang {
		shun = [][]int{}
		ke = [][]int{}
		tem := mj.DeepCopy(rs)
		tem[card] -= 2 //减掉将牌数量
		//fmt.Printf("+++++++++++++++++++++++++++  card 【%v】 +++++++++++++++++++++++++++  \n", card)
		for _, c := range keys {
			_, hasNext := tem[c+1]
			_, hasNextMore := tem[c+2]
			if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
				if tem[c+1] > 0 && tem[c+2] > 0 {
					shun = append(shun, []int{c, c + 1, c + 2})
					tem[c] -= 1
					tem[c+1] -= 1
					tem[c+2] -= 1
				}
			}
			_, hasNext = tem[c+1]
			_, hasNextMore = tem[c+2]
			if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
				if tem[c+1] > 0 && tem[c+2] > 0 {
					shun = append(shun, []int{c, c + 1, c + 2})
					tem[c] -= 1
					tem[c+1] -= 1
					tem[c+2] -= 1
				}
			}
			_, hasNext = tem[c+1]
			_, hasNextMore = tem[c+2]
			if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
				if tem[c+1] > 0 && tem[c+2] > 0 {
					shun = append(shun, []int{c, c + 1, c + 2})
					tem[c] -= 1
					tem[c+1] -= 1
					tem[c+2] -= 1
				}
			}
			_, hasNext = tem[c+1]
			_, hasNextMore = tem[c+2]
			if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
				if tem[c+1] > 0 && tem[c+2] > 0 {
					shun = append(shun, []int{c, c + 1, c + 2})
					tem[c] -= 1
					tem[c+1] -= 1
					tem[c+2] -= 1
				}
			}
			if tem[c] == 3 { //找出刻子
				ke = append(ke, []int{c, c, c})
				tem[c] -= 3
			}
			if tem[c] == 4 { //找出大刻子
				ke = append(ke, []int{c, c, c, c})
				tem[c] -= 4
			}
		}
		sum := m.SumMap(tem)
		//fmt.Printf("tem : %v \n", tem)
		//fmt.Printf("shun : %v \n", shun)
		//fmt.Printf("ke : %v \n", ke)
		//fmt.Printf("sum : %v \n", sum)
		if sum > 0 {
			//fmt.Println("-----------------------------------------next loop start------------------------------------------------")
			shun = [][]int{}
			ke = [][]int{}
			tem = mj.DeepCopy(rs)
			tem[card] -= 2 //减掉将牌数量
			for _, c := range keys {
				if tem[c] == 3 { //找出刻子
					ke = append(ke, []int{c, c, c})
					tem[c] -= 3
				}
				if tem[c] == 4 { //找出大刻子
					ke = append(ke, []int{c, c, c, c})
					tem[c] -= 4
				}
				_, hasNext := tem[c+1]
				_, hasNextMore := tem[c+2]
				if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
					if tem[c+1] > 0 && tem[c+2] > 0 {
						shun = append(shun, []int{c, c + 1, c + 2})
						tem[c] -= 1
						tem[c+1] -= 1
						tem[c+2] -= 1
					}
				}
				_, hasNext = tem[c+1]
				_, hasNextMore = tem[c+2]
				if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
					if tem[c+1] > 0 && tem[c+2] > 0 {
						shun = append(shun, []int{c, c + 1, c + 2})
						tem[c] -= 1
						tem[c+1] -= 1
						tem[c+2] -= 1
					}
				}
				_, hasNext = tem[c+1]
				_, hasNextMore = tem[c+2]
				if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
					if tem[c+1] > 0 && tem[c+2] > 0 {
						shun = append(shun, []int{c, c + 1, c + 2})
						tem[c] -= 1
						tem[c+1] -= 1
						tem[c+2] -= 1
					}
				}
				_, hasNext = tem[c+1]
				_, hasNextMore = tem[c+2]
				if tem[c] > 0 && hasNext && hasNextMore { //找出顺子
					if tem[c+1] > 0 && tem[c+2] > 0 {
						shun = append(shun, []int{c, c + 1, c + 2})
						tem[c] -= 1
						tem[c+1] -= 1
						tem[c+2] -= 1
					}
				}
			}
			//fmt.Printf("shun : %v \n", shun)
			//fmt.Printf("ke : %v \n", ke)
			//fmt.Printf("tem : %v \n", tem)
			//fmt.Println("-----------------------------------------next loop end------------------------------------------------")
		}
		sum = m.SumMap(tem)
		//fmt.Printf("sum : %v \n", sum)
		if sum == 0 {
			huRes = make([][]int, 0)
			huRes = append(huRes, shun...)
			huRes = append(huRes, ke...)
			huRes = append(huRes, []int{card, card})
			return huRes, true
		}
	}
	return nil, false
}

func (m *Mj) CheckQidui(countValues map[int]int) (huRes [][]int, ok bool) {
	if len(countValues) != 7 {
		return nil, false
	}
	for card, _ := range countValues {
		huRes = append(huRes, []int{card, card})
	}
	return huRes, true
}
